#include "StompedReality/Core/GameTime.h"
#include "StompedReality/Core/Graphics/RenderSystem.h"
#include "StompedReality/Core/IGame.h"
#include "StompedReality/Core/Input/InputSystem.h"
#include "StompedReality/Core/Memory/ObjectPoolManager.h"
#include "StompedReality/Core/Task/BaseTasks.h"

CreateRegDummy( Task )

namespace StompedReality
{
namespace Core
{

void UpdateGameTimeTask::Exectue( StompedReality::IGame* game ) {
  game->getGameTime( )->updateTime( );
}

static int gtpReg = *(int*) StompedReality::type_system::TypeSystem::CreateTypeInfo<UpdateGameTimeTask> (
    "UpdateGameTime" );

void BeginRenderTask::Exectue( StompedReality::IGame* game ) {
  game->RenderSystem( )->BeginRendering( );
}

static int bRendReg = *(int*) StompedReality::type_system::TypeSystem::CreateTypeInfo<BeginRenderTask> (
    "StartRendering" );

void EndRenderTask::Exectue( StompedReality::IGame* game ) {
  game->RenderSystem( )->EndRendering( );
}

static int eRendReg = *(int*) StompedReality::type_system::TypeSystem::CreateTypeInfo<EndRenderTask> (
    "EndRendering" );

void SwapBufferRenderTask::Exectue( StompedReality::IGame* game ) {
  game->RenderSystem( )->SwapBuffer( );
}

static int swbRendReg = *(int*) StompedReality::type_system::TypeSystem::CreateTypeInfo<SwapBufferRenderTask> (
    "SwapBuffer" );

void UpdateInputTask::Exectue( StompedReality::IGame* game ) {
  game->InputSystem( )->HandleInput( );
}

static int upInpReg = *(int*) StompedReality::type_system::TypeSystem::CreateTypeInfo<UpdateInputTask> (
    "UpdateInput" );

void DrawComponentTask::Exectue( StompedReality::IGame* game ) {
  MemoryBlock<Component>* cmpBlock = game->getComponentSystem( )->GetMemoryBlock( this->TypeID );

  //std::cout << "DR: " << this->TypeName << ", "  << cmpBlock->GetCapacity() << std::endl;
  for ( int i = 0; i < cmpBlock->GetCapacity( ); ++i )
  {
    if ( cmpBlock->IsObjectAt ( i ) )
    {
      //std::cout << "\tDR cmp: " << i << std::endl;
      cmpBlock->GetObjectAt ( i )->Draw ( );
    }
  }
}

void DrawComponentTask::Initialize ( )
{
  LogInfoPair( "Component Type", this->TypeName );
  this->TypeID = StompedReality::type_system::TypeSystem::GetTypeID ( this->TypeName.c_str( ) );
}

static int cmpDrawReg = *(int*) (StompedReality::type_system::TypeSystem::CreateTypeInfo<DrawComponentTask> (
                                   "DrawComponent" )->
                                 addTypeField ( StompedReality::type_system::TypeField ( "component",
                                                                                         &DrawComponentTask::TypeName ) ) );

void UpdateComponentTask::Exectue( StompedReality::IGame* game ) {
  MemoryBlock<Component>* cmpBlock = game->getComponentSystem( )->GetMemoryBlock( this->TypeID );
  for ( int i = 0; i < cmpBlock->GetCapacity( ); ++i )
  {
    if ( cmpBlock->IsObjectAt ( i ) )
    {
      cmpBlock->GetObjectAt ( i )->Update ( );
    }
  }
}

void UpdateComponentTask::Initialize ( )
{
  LogInfoPair( "Component Type", this->TypeName );
  this->TypeID = StompedReality::type_system::TypeSystem::GetTypeID ( this->TypeName.c_str( ) );
}

static int cmpUpdateReg = *(int*) (StompedReality::type_system::TypeSystem::CreateTypeInfo<UpdateComponentTask> (
                                     "UpdateComponent" )->
                                   addTypeField ( StompedReality::type_system::TypeField ( "component",
                                                                                           &UpdateComponentTask::
                                                                                           TypeName ) ) );

}
}